/*
 * @(#)StmntValueObj.java
 *
 *
 * Project: APEP-JZCG 
 *
 * Modify Information:
 * =============================================================================
 *   Author       Date       Description
 *   ------------ ---------- ---------------------------------------------------
 *   john        2008-08-08  First release
 *   john        2008-08-11  增加and和or操作
 *
 * Copyright Notice:
 * =============================================================================
 *    Copyright (c) 2001-2007 Auto-Parts E-Procurement Co., Ltd. 
 *        No.251-1 Wuning Road, Shanghai, 200063, China All rights reserved.
 *
 *    This software is the confidential and proprietary information of
 *        Auto-Parts E-Procurement Co., Ltd. ("Confidential Information").
 *        You shall not disclose such Confidential Information and shall use it
 *        only in accordance with the terms of the license agreement you entered
 *        into with APEP.
 *
 * Warning:
 * =============================================================================
 *   
 * 
 */
package com.hitrust.gs.lib.db;

import java.util.ArrayList;

import com.hitrust.gs.util.exception.GSException;

/**
 * 参数对象
 */
public class ConditionValueObj {

    public static final int EQUAL         = 0;
    public static final int GREATER_EQUAL = 1 ;
    public static final int GREATER_THAN  = 2 ;
    public static final int LESS_EQUAL    = 3 ;
    public static final int LESS_THAN     = 4 ;
    public static final int NOT_EQUAL     = 5 ;
    public static final int LIKE          = 6 ;
    public static final int LIKELEFT      = 7 ;
    public static final int LIKERIGHT     = 8 ;
    
    public static final int IN            = 9;
    public static final int BETWEEN       = 10;
    public static final int NOT_IN        = 11;
    
    public static final int TYPE_MIN      = 0 ;
    public static final int TYPE_MAX      = 11 ;
    
    private int iType;
    
    private String iName;
    
    private Object[] iValue;
    
    private ArrayList iValues;
    
    private String iSql;
    
    private int  iSqlStatus;  //0-new ,1-and ,2-or

    /**
     * 缺省的构造器
     * @param aName .   参数对象的字段名称.
     * @param aValue.   参数对象的值.
     * @param aOprType. 条件操作类型
     * @throws GSException 
     */
    public ConditionValueObj(String aName, Object aValue,int aOprType) throws GSException {
        Object[] tValue ={aValue};
        initValueObj(aName,tValue,aOprType) ;
    }
    
    /**
     * 缺省的构造器
     * @param aName .   参数对象的字段名称.
     * @param aValue.   参数对象的值.
     * @param aOprType. 条件操作类型
     * @throws Exception 
     */
    public ConditionValueObj(String aName, Object aValue[],int aOprType) throws GSException {
        initValueObj(aName,aValue,aOprType) ;
    }
    
    /**
     * 缺省的构造器
     * @param aName .   参数对象的字段名称.
     * @param aValue.   参数对象的值.
     * @param aOprType. 条件操作类型
     * @throws Exception 
     */
    private void  initValueObj(String aName, Object aValue[],int aOprType) throws GSException {
        iSqlStatus = 0;
        iValues = new ArrayList();
        setName(aName);
        parameterCheck(aValue,aOprType);
        setType(aOprType);
        setValue(aValue);

        iSql   = buildConditionSql();
    }

    /**
     * @param aValue the value to set
     */
    private void setValue(Object[] aValue) {

        if(aValue != null){
            for(int i=0;i<aValue.length;i++){
                if(aValue[i] != null)
                    iValues.add(fixValue(aValue[i]));
            }
            iValue = iValues.toArray();
        }
    }

    /**
     * @return the name
     */
    public String getName() {
        return this.iName;
    }
    
    /**
     * @param aName the name to set
     * @throws Exception 
     */
    private void setName(String aName) throws GSException {
        if(aName!= null && aName.trim().length()!=0)
            this.iName = aName;
        else {
            throw new GSException("字段名不能为空："+aName);
        }
    }
    
    /**
     * @param aType the type to set
     * @throws Exception 
     */
    private void setType(int aType) throws GSException {
        if(aType >= TYPE_MIN  && aType <=TYPE_MAX)
            this.iType = aType;
        else {
            throw new GSException("未知的操作符："+aType);
        }
    }


    /**
     * 返回当前条件的对象
     * @return the value
     */
    private Object fixValue(Object aValue) {
        Object tValue = aValue;
        if(iType ==LIKE)
            tValue="%"+tValue+"%";
        
        if(iType ==LIKELEFT)
            tValue=tValue+"%";
        
        if(iType ==LIKERIGHT)
            tValue="%"+tValue;
            
        return tValue;
    }
    
    private boolean parameterCheck(Object aValue[],int aOprType) throws GSException{
        
        if(aValue == null)
            return false;
        switch(aOprType){
            case EQUAL:
            case GREATER_EQUAL:
            case GREATER_THAN:
            case LESS_EQUAL:
            case LESS_THAN:
            case NOT_EQUAL:
            case LIKE:
            case LIKELEFT:
            case LIKERIGHT:
                if(aValue.length !=1)
                    throw new GSException("参数不合法,一元操作的参数不为1，传入参数个数："+aValue.length);
                if(aValue[0] != null && aValue[0].toString().trim().length()==0){
                    aValue = null;
                }
                break;
            case BETWEEN:
                if(aValue.length <1)
                    throw new GSException("参数不合法,二元操作的参数不为2，传入参数个数："+aValue.length);
                break;
            case IN:
            case NOT_IN:
                if(aValue.length <1)
                    throw new GSException("参数不合法,多元操作的参数小于1，传入参数个数："+aValue.length);
                for(int i=0;i<aValue.length;i++){
                    if(aValue[i] != null && aValue[i].toString().trim().length()==0){
                        aValue[i] = null;
                    }
                }
                break;
            default:
                throw new GSException("未知的操作符："+iType);
            }
        return true;
    }
    
    /**
     * 返回所有的值对象
     * @return
     */
    public Object[] getValues() {
        
        return this.iValues.toArray();
    }
    
    /**
     * 根据条件名和操作符生成对应的sql条件。
     * @return
     */
    private String buildConditionSql(){
        
        String tCondition = "";
        if(iName != null && iValue != null) {
            switch(iType){
            
            case EQUAL:
                tCondition = iName+" = ? ";
                break;
            case GREATER_EQUAL:
                tCondition = iName+" >= ? ";
                break;
            case GREATER_THAN:
                tCondition = iName+" > ? ";
                break;
            case LESS_EQUAL:
                tCondition = iName+" <= ? ";
                break;
            case LESS_THAN:
                tCondition = iName+" < ? ";
                break;
            case NOT_EQUAL:
                tCondition = iName+" <> ? ";
                break;
            case LIKE:
            case LIKELEFT:
            case LIKERIGHT:
                tCondition = iName+" like ? ";
                break;
            case IN:
                tCondition = iName+" in(?";
                for(int i=1;i<iValue.length;i++){
                    tCondition += ",?";
                }
                tCondition +=") ";
                break;
            case BETWEEN:
                tCondition = iName+ " between ? and ? ";
                break;
            case NOT_IN:
                tCondition = iName+" not in(?";
                for(int i=1;i<iValue.length;i++){
                    tCondition += ",?";
                }
                tCondition += ") ";
                break;
                
            default:
                iType = LIKE;
                tCondition = iName+" like ? ";
            }
        }
        if(!tCondition.equals(""))
            tCondition  = " "+ tCondition;
        
        return tCondition;
    }
    
    /**
     * 返回生成的条件
     * @return
     */
    public String getConditionSql(){
        
        if(iSqlStatus != 0)
            return "("+iSql+")";
        else
            return iSql;
    }
    
    /**
     * 
     * @param aConditionValueObj
     */
    public void and(ConditionValueObj aConditionValueObj){
        
        if(aConditionValueObj != null){
            String tTmpSql = aConditionValueObj.getConditionSql();
            if(!"".equals(iSql) && !"".equals(tTmpSql)) {
                
                if(iSqlStatus ==2){
                    iSql = "("+iSql+")";
                }
                iSql =iSql+" and "+tTmpSql;
                iSqlStatus =1;
            }else if(!"".equals(tTmpSql)){
                iSql = tTmpSql;
            }
            
            Object[] tObjs = aConditionValueObj.getValues();
            for(int i=0;i<tObjs.length;i++){
                iValues.add(tObjs[i]);
            }
        }
        
    }
    
    /**
     * 
     * @param aConditionValueObj
     */
    public void or(ConditionValueObj aConditionValueObj){
        
        if(aConditionValueObj != null){

            String tTmpSql = aConditionValueObj.getConditionSql();
            if(!"".equals(iSql) && !"".equals(tTmpSql)) {
                
                if(iSqlStatus ==1){
                    iSql = "("+iSql+")";
                }
                iSql =iSql+" or "+tTmpSql;
                iSqlStatus =2;
            }else if(!"".equals(tTmpSql)){
                iSql = tTmpSql;
            }
            
            Object[] tObjs = aConditionValueObj.getValues();
            for(int i=0;i<tObjs.length;i++){
                iValues.add(tObjs[i]);
            }
         }
    }


}
